﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mahanet.Abyss.PathCalculation
{
	public class Rectangle3D
	{
		#region Fields

		public Vector3D m_WidthVector;
		public Vector3D m_HeightVector;

		#endregion

		#region C'tor

		public Rectangle3D(Coordinate3D bottomLeftCorner, Vector3D widthVector, Vector3D heightVector)
		{
			this.BottomLeftCorner = bottomLeftCorner;
			m_WidthVector = widthVector;
			m_HeightVector = heightVector;
			if (!PrecisionUtils.IsZero(m_WidthVector.Dot(m_HeightVector)))
				throw new ArgumentException("Given vectors are not perpendicular; this is not a rectangle.");

			RectanglePlane = new Plane3D(widthVector.Cross(heightVector), bottomLeftCorner);
		}

		#endregion

		#region Public Properties

		public Plane3D RectanglePlane { get; private set; }

		public Coordinate3D BottomLeftCorner { get; private set; }
		public Coordinate3D TopLeftCorner { get { return BottomLeftCorner + m_HeightVector; } }
		public Coordinate3D BottomRightCorner { get { return BottomLeftCorner + m_WidthVector; } }
		public Coordinate3D TopRightCorner { get { return BottomLeftCorner + m_HeightVector + m_WidthVector; } }

		public bool IsPointOnRectangle(Coordinate3D point)
		{
			// TODO: write tests
			if (!RectanglePlane.IsPointOnPlane(point))
				return false;

			Vector3D bottomLeftToPointVector = new Vector3D(BottomLeftCorner, point);
			double projectionOnWidth = bottomLeftToPointVector.Dot(m_WidthVector);
			if (projectionOnWidth < 0 || projectionOnWidth > m_WidthVector.Length())
				return false;

			double projectionOnHeight = bottomLeftToPointVector.Dot(m_HeightVector);
			if (projectionOnHeight < 0 || projectionOnHeight > m_HeightVector.Length())
				return false;

			return true;
		}

		#endregion
	}
}
